package gobytes

import (
	"unsafe"
)

type Endianness byte

const (
	BigEndian Endianness = iota
	LittleEndian
	int16Len = 2
	int32Len = 4
	int64Len = 8
)

func Int16ToBytes(value int16, endianness Endianness) []byte {
	bytes := make([]byte, int16Len)
	switch endianness {
	case BigEndian:
		for i := 0; i < int16Len; i++ {
			bytes[i] = byte((value >> ((int16Len - i - 1) * 8)) & 0xFF)
		}
	case LittleEndian:
		for i := 0; i < int16Len; i++ {
			bytes[i] = byte((value >> (i * 8)) & 0xFF)
		}
	}
	return bytes

}

func Int32ToBytes(value int32, endianness Endianness) []byte {
	bytes := make([]byte, int32Len)
	switch endianness {
	case BigEndian:
		for i := 0; i < int32Len; i++ {
			bytes[i] = byte((value >> ((int32Len - i - 1) * 8)) & 0xFF)
		}
	case LittleEndian:
		for i := 0; i < int32Len; i++ {
			bytes[i] = byte((value >> (i * 8)) & 0xFF)
		}
	}
	return bytes
}

func Int64ToBytes(value int64, endianness Endianness) []byte {
	bytes := make([]byte, int64Len)
	switch endianness {
	case BigEndian:
		for i := 0; i < int64Len; i++ {
			bytes[i] = byte((value >> ((int64Len - i - 1) * 8)) & 0xFF)
		}
	case LittleEndian:
		for i := 0; i < int64Len; i++ {
			bytes[i] = byte((value >> (i * 8)) & 0xFF)
		}
	}
	return bytes
}

//IntToBytes 将int类型值转换为byte切片
func IntToBytes(value int, endianness Endianness) []byte {
	byteCount := int(unsafe.Sizeof(value))
	bytes := make([]byte, byteCount)
	switch endianness {
	case BigEndian:
		for i := 0; i < byteCount; i++ {
			bytes[i] = byte((value >> ((byteCount - i - 1) * 8)) & 0xFF)
		}
	case LittleEndian:
		for i := 0; i < byteCount; i++ {
			bytes[i] = byte((value >> (i * 8)) & 0xFF)
		}
	}
	return bytes
}

// BytesToInt16 bytes切片转换int16类型的值
func BytesToInt16(bytes []byte, endianness Endianness) int16 {
	var res int16
	switch endianness {
	case BigEndian:
		// 10010011 00101010 => 10010011 00000000 | 00000000 00101010 = 10010011 00101010
		res = int16(bytes[0])<<8 | int16(bytes[1])
	case LittleEndian:
		// 10010011 00101010 => 00101010 00000000 | 00000000 10010011 = 00101010 10010011
		res = int16(bytes[0]) | int16(bytes[1])<<8
	}
	return res
}
